package top.novel.ui;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import top.novel.persistence.PersistenceData;
import top.novel.persistence.PersistenceService;
import top.novel.strategy.IStrategy;

import javax.swing.*;
import java.util.List;

/**
 * @author xuhainan
 * @date 2022/8/8 16:18
 * @region hefei
 */
public class NovelForm {
    private JPanel novelPanel;
    private JButton preButton;
    private JButton nextButton;
    private JPanel contentPanel;
    private JTextPane content;
    private JScrollPane scrollPane;
    private JButton refreshButton;
    private JTextField urlText;
    private JButton submitButton;
    private final Injector injector;

    public NovelForm(Project project, ToolWindow toolWindow, Injector injector) {
        this.injector = injector;
        PersistenceData data = fillContent(null);
        if (data != null) {
            PersistenceService.getInstance().loadState(data);
        }
        preButton.addActionListener(e -> {
            PersistenceData persistenceData = fillContent(true);
            if (persistenceData != null) {
                PersistenceService.getInstance().loadState(persistenceData);
            }
        });
        nextButton.addActionListener(e -> {
            PersistenceData persistenceData = fillContent(false);
            System.out.println("next page info ：" + JSONUtil.toJsonStr(persistenceData));
            if (persistenceData != null) {
                PersistenceService.getInstance().loadState(persistenceData);
            }
        });

        refreshButton.addActionListener(e -> {
            PersistenceData refreshData = fillContent(null);
            if (refreshData != null) {
                PersistenceService.getInstance().loadState(refreshData);
            }
        });

        submitButton.addActionListener(e -> {
            String urlTextText = urlText.getText();
            if (StrUtil.isNotBlank(urlTextText)) {
                TypeLiteral<IStrategy> strategyTypeLiteral = new TypeLiteral<>() {
                };
                if (injector.findBindingsByType(strategyTypeLiteral)
                        .stream()
                        .anyMatch(strategy -> strategy.getProvider().get().predicate().test(urlTextText))) {
                    PersistenceService persistenceService = PersistenceService.getInstance();
                    PersistenceData persistenceData = persistenceService.getPersistenceData();
                    persistenceData.setUrl(urlTextText);
                    persistenceService.loadState(persistenceData);
                    PersistenceData submitData = fillContent(null);
                    if (submitData != null) {
                        PersistenceService.getInstance().loadState(submitData);
                    }
                }
            }
        });
    }

    public PersistenceData fillContent(Boolean isPre) {
        PersistenceData initData = PersistenceService.getInstance().getPersistenceData();
        if (initData != null && StrUtil.isNotBlank(initData.getUrl()) && initData.getUrl().endsWith("html")) {
            String recallUrl = initData.getUrl();
            if (Boolean.TRUE.equals(isPre)) {
                recallUrl = initData.getPreUrl();
            }
            if (Boolean.FALSE.equals(isPre)) {
                recallUrl = initData.getNextUrl();
            }
            // urlText
            urlText.setText(recallUrl);
            PersistenceData persistenceData = new PersistenceData();
            persistenceData.setUrl(recallUrl);

            TypeLiteral<IStrategy> strategyTypeLiteral = new TypeLiteral<>() {
            };
            List<Binding<IStrategy>> strategyBindings = injector.findBindingsByType(strategyTypeLiteral);
            for (Binding<IStrategy> strategyBinding : strategyBindings) {
                IStrategy strategy = strategyBinding.getProvider().get();
                if (strategy.predicate().test(recallUrl)) {
                    strategy.analyze(content, persistenceData);
                }
            }
            return persistenceData;
        } else {
            return null;
        }
    }

    public JPanel getNovelPanel() {
        return novelPanel;
    }

    public JButton getPreButton() {
        return preButton;
    }

    public JButton getNextButton() {
        return nextButton;
    }

    public JPanel getContentPanel() {
        return contentPanel;
    }

    public JTextPane getContent() {
        return content;
    }

}
